home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / RGASM.RAR / ASMCODE.EXE / CHAPT11 / TSRPGM.ASM < prev   
Encoding:
Assembly Source File  |  1993-06-05  |  47.2 KB  |  1,004 lines

  1. ;************************************************************************
  2. ;                                                                       *
  3. ;  Resident program of starting prescribed job                          *
  4. ;                                                                       *
  5. ;  Activated on pressing: Alt + "hot"key (K)                            *
  6. ;                                                                       *
  7. ;  Author: SOPIN  A.I.  VSU,  Voronezh                                  *
  8. ;                                                                       *
  9. ;                                                                       *
  10. ;  Call:  EXEC TSRPGM /PATH [/PARM /S /K=40]                            *                                                              *
  11. ;  -----                                                                *
  12. ;  PATH - path to job to be started, e.g.:  D:\SYST0\dserv.exe          *
  13. ;        (positional parameter, the rest are key parameters)            *
  14. ;                                                                       *
  15. ;  PARM - list of parameters to be passed                               *
  16. ;                                                                       *
  17. ;  S    - saving screen to be restored afterwards                       *
  18. ;                                                                       *
  19. ;  K=XX -hex code of "hot" key                                          *
  20. ;                                                                       *
  21. ;                                                                       *
  22. ;  Alt + Shift (Right)  -deinstallation of  driver                       *
  23. ;                                                                       *
  24. ;                                                                       *
  25. ;  Interrupts used:  INT 08h, INT 09h, INT 13h, INT 28h                 *
  26. ;                                                                       *
  27. ;                                                                       *
  28. ;                                                                       *
  29. ;************************************************************************
  30. NAME     TSRPGM
  31. ;  Saving of registers to be used
  32. PUSHR    MACRO  REGLST
  33.          IFB    <REGLST>
  34.          push   ax
  35.          push   bx
  36.          push   cx
  37.          push   dx
  38.          push   si
  39.          push   di
  40.          push   ds
  41.          push   es
  42.          push   bp
  43.          ENDIF
  44.          IRP    REG,<REGLST>
  45.          push   REG
  46.          ENDM
  47.          ENDM
  48. ;  Restoring registers been used
  49. POPR     MACRO  REGLST
  50.          IFB    <REGLST>
  51.          pop    bp
  52.          pop    es
  53.          pop    ds
  54.          pop    di
  55.          pop    si
  56.          pop    dx
  57.          pop    cx
  58.          pop    bx
  59.          pop    ax
  60.          ENDIF
  61.          IRP    REG,<REGLST>
  62.          pop    REG
  63.          ENDM
  64.          ENDM
  65. ;----------------------------------------------------------
  66. CODE     SEGMENT
  67.          ASSUME CS:CODE,DS:CODE,ES:CODE
  68.          ORG    100h                    ;  PSP
  69. START:   jmp    BEGIN                   ;  jumping to loading of driver
  70. ;----------------------------------------------------------
  71. STAC     DB     4096 dup (0)
  72. ERR00    DB     '*** TSRPGM ***  DOS is active !!! ', 0
  73. ERR01    DB     '*** TSRPGM ***  Invalid function number ! ', 0
  74. ERR02    DB     '*** TSRPGM ***  File is not found !!!', 0
  75. ERR03    DB     '*** TSRPGM ***  Path is not found !!!', 0
  76. ERR04    DB     '*** TSRPGM ***  Too many files been opened !!!', 0
  77. ERR05    DB     '*** TSRPGM ***  Access is not allowed !!!', 0
  78. ERR06    DB     '*** TSRPGM ***  Error in logical number !!!', 0
  79. ERR07    DB     '*** TSRPGM ***  Block of memory control is destroyed !!!', 0
  80. ERR08    DB     '*** TSRPGM ***  Lack of memory !!!', 0
  81. ERR09    DB     '*** TSRPGM ***  Error of memory block address !!!', 0
  82. ERR10    DB     '*** TSRPGM ***  Wrong operating environment !!!', 0
  83. ERR11    DB     '*** TSRPGM ***  Invalid format !!!', 0
  84. TEXT0    DB     'Driver *** TSRPGM ***  is deinstalled !!!', 0
  85. ADRERR   DW     ERR01, ERR02, ERR03, ERR04, ERR05, ERR06
  86.          DW     ERR07, ERR08, ERR09, ERR10, ERR11
  87. DOSFLG   LABEL  DWORD                   ;  address of DOS activity indicator
  88. OFFFLG   DW     0                       ;  offset of activity indicator:   BX
  89. SEGFLG   DW     0                       ;  segment address of activity indicator: ES
  90. ;
  91. OLD09H   LABEL  DWORD                   ;  address of standart vector  INT 09H
  92. OFF09H   DW     0                       ;  offset of standart   INT 09h
  93. SEG09H   DW     0                       ;  segment address of  INT 09h
  94. ;
  95. OLD13H   LABEL  DWORD                   ;  entry point of standart  INT13H
  96. OFF13H   DW     0                       ;  address of old vector  INT13H
  97. SEG13H   DW     0                       ;  segment address of old  INT13H
  98. ;
  99. OLD28H   LABEL  DWORD                   ;  entry point of standart INT28H
  100. OFF28H   DW     0                       ;  address of old vector  INT28H
  101. SEG28H   DW     0                       ;  segment address of old  INT28H
  102. ;
  103. SSKEEP   DW     0                       ;
  104. SPKEEP   DW     0                       ;
  105. OLDPSP   DW     0                       ;
  106. PSP0     DW     0                       ;
  107. DTANEW   DW     64 dup (0)
  108. DTAADR   LABEL  DWORD
  109. DTAOFF   DW     0
  110. DTASEG   DW     0
  111. VIDEO    DW     0                       ;  address of videobuffer
  112. CURSX    DB     0                       ;  position of cursor
  113. CURSY    DB     0                       ;  line of cursor
  114. MODE     DB     0                       ;  display mode
  115. FLAG0    DB     0                       ;  flag of starting a job
  116. FLAG1    DB     0                       ;  flag of activity of a job
  117. EOS      DB     0                       ;  indicator of end of ASCIIZ -string
  118. DL0      DB     0                       ;  cursor set position
  119. ;
  120. InBios   DB     0                       ;  activity flag of INT 13h (BIOS)
  121. ALT0     DB     0                       ;  previous  Alt
  122. SCAN0    DB     0                       ;  scan-code of key (after  Alt)
  123. KEY0     DB     40h                     ;  -82 code of prescibed key (after Alt)
  124. SAV      DB     0                       ;  -81 sceen saving flag
  125. PARAM    DW     7 DUP (0)               ;  -80
  126. PATH     DB     64 dup (0)              ;  -66 path for starting
  127. PRES     DW     1234                    ;  -2  driver presence code
  128.  
  129. ;----------------------------------------------------------
  130. ;
  131. ;  New  handler  for INT09h
  132. ;
  133. ;  Alt + F6            -starting subordinate job
  134. ;
  135. ;  Alt + Shift (Right) -driver deinstallation
  136. ;
  137. ;
  138. ;
  139. ;----------------------------------------------------------
  140. INT09H   PROC   FAR                  ;  new handler for  INT 09h
  141.          cli                         ;  disable interrupts
  142.          PUSHR                       ;
  143.          mov    ax,40h               ;  keyboard data
  144.          mov    ES,ax                ;  segment address for BIOS
  145.          mov    ch,ES:[17h]          ;  register keys state
  146.          and    ch,09h               ;  clear bits out of interest
  147.          mov    CS:ALT0,ch           ;
  148.          in     al,60h               ;  getting scan-code
  149.          mov    CS:SCAN0,al          ;  saving scan-code
  150. ;  Check for driver deinstallation (Alt + Shift (Right))
  151.          mov    cl,ES:[17h]          ;  register keys state byte
  152.          and    cl,09h               ;  clear bits out of interest
  153.          or     cl,ch                ;
  154.          cmp    cl,09h               ;  Alt + Shift (right) ?
  155.          jne    AltF6                ;
  156.          pushf                       ;  flag register for  IRET (from INT 09H)
  157.          Call   CS:OLD09H            ;  call of old handler for INT 09H
  158.          Call   DEINST               ;  driver deinstallation
  159.          POPR                        ;  restore registers
  160.          sti                         ;  enable interrupts
  161.          IRET                        ;  exit interrupt handling
  162. ;  Check of starting of a prescribed job ("hot" key Alt + KEY0)
  163. AltF6:   and    ch,08h               ;  clear flags out of interest
  164.          cmp    ch,08h               ;  previous  Alt ?
  165.          jne    RET09                ;
  166.          mov    al,CS:KEY0           ;  "hot" key code
  167.          cmp    CS:SCAN0,al          ;  Alt + KEY0 - indicator of job started
  168.          jne    RET09                ;
  169.          cmp    CS:FLAG1,1           ;  job is active
  170.          je     RET09                ;
  171. ;  Handling "hot" key code -starting a job
  172.          mov    CS:FLAG0,1           ;  indicator of job started
  173.          in     al,61h               ;  keyboard control port
  174.          or     al,80h               ;  permisson bit
  175.          out    61h,al               ;  send affirmation
  176.          and    al,7Fh               ;  clear affirmation bit
  177.          out    61h,al               ;  send to port  B
  178.          mov    al,20h               ;  mask for 8259A chip
  179.          out    20h,al               ;  affirmation of interrupt handling
  180.          POPR                        ;  restore registers
  181.          sti                         ;  enable interrupts
  182.          IRET                        ;  exit interrupt handling
  183. ;  Restoring registers end exit
  184. RET09:   pushf                       ;  flag register for  IRET (from INT 09H)
  185.          Call   CS:OLD09H            ;  call old handler for  INT 09H
  186.          POPR                        ;  restore registers
  187.          sti                         ;  enable interrupts
  188.          IRET                        ;  exit interrupt handling
  189. INT09H   ENDP
  190.  
  191. ;----------------------------------------------------------
  192. ;
  193. ;  Procedure for starting of a prescribed job (on Alt + KEY0)
  194. ;
  195. ;  Timer interrupt INT 08H is used
  196. ;
  197. ;
  198. ;----------------------------------------------------------
  199. INT08H  PROC    FAR
  200.         cli                             ;  disable interrupts
  201.         cmp     CS:FLAG0,1              ;  job started ?
  202.         jne     OLD08                   ;  no
  203.         cmp     CS:FLAG1,1              ;  job active ?
  204.         je      OLD08                   ;  wait for finish
  205.         cmp     CS:InBios,1             ;  exchange with disk ?
  206.         je      OLD08                   ;   wait for finish
  207.         PUSHR   <es,bx>                 ;
  208.         LES     bx,CS:DOSFLG            ;  address of DOS activity flag
  209.         cmp     byte ptr ES:[bx],0      ;  DOS not active ?
  210.         POPR    <bx,es>                 ;
  211.         jnz     OLD08                   ;   wait for finish
  212. ;  Constructing stack for starting a job (on IRET from  INT 08h)
  213.         PUSHR                           ;  registers of interrupted job
  214.         pushf                           ;  flags register for IRET (INT 08h)
  215.         push    cs                      ;  segment address for exit
  216.         lea     cx,ACTIV                ;  address of program for starting job
  217.         push    cx                      ;  put onto stack for  IRET
  218. OLD08:  DB      0EAh                    ;  code of  JMP FAR ...  instruction
  219. OLD08H  LABEL   DWORD                   ;  entry point of standard INT08H
  220. OFF08H  DW      0                       ;  address of old vector  INT08H
  221. SEG08H  DW      0                       ;  segment address of old  INT08H
  222. INT08H  ENDP
  223.  
  224.  
  225. ;----------------------------------------------------------
  226. ;
  227. ;  Activating the resident program (on Alt + F6)
  228. ;
  229. ;  Dynamic start of prescribed job
  230. ;
  231. ;
  232. ;----------------------------------------------------------
  233. ACTIV   PROC    FAR
  234.         cli
  235.         mov     CS:SSKEEP,SS      ;  save SS register
  236.         mov     CS:SPKEEP,SP      ;  save SP register
  237.         mov     ax,cs             ;
  238.         mov     SS,ax             ;  segment of new stack
  239.         lea     SP,STAC+4096      ;  switch to interior stack
  240.         Call    SAVESCR           ;  save screen
  241.         mov     ah,2fh            ;  read address of current DTA
  242.         int     21h               ;
  243.         cli
  244.         mov     CS:DTASEG,es      ;
  245.         mov     CS:DTAOFF,bx      ;  save  DTA address
  246. ;  Save old process (address of PSP of interrupted program)
  247.         mov     ah,62h            ;
  248.         int     21h               ;  GetProcess
  249.         mov     CS:OLDPSP,bx      ;  PSP  of interrupted process
  250.         cli
  251.         mov     ax,cs             ;
  252.         mov     ds,ax             ;
  253.         lea     dx,CS:DTANEW      ;  DS:DX  -address of new  DTA
  254.         mov     ah,1ah            ;
  255.         int     21h               ;  set new  DTA
  256.         cli
  257.         mov     bx,CS:PSP0        ;  address of PSP of resident program
  258.         mov     ah,50h            ;
  259.         int     21h               ;  SetProcess
  260. ;  Dynamic start of job
  261.         mov     CS:FLAG0,0        ;  clear flag of starting a job
  262.         mov     CS:FLAG1,1        ;  job activity flag
  263.         cli
  264.         mov     ax,cs             ;
  265.         mov     ds,ax             ;  segment address of path and name of file
  266.         mov     es,ax             ;  EX-  segment address of data
  267.         lea     bx,PARAM          ;  BX -offset of parameters address
  268.         lea     dx,PATH           ;  offset of path and name of file
  269.         mov     ah,4Bh            ;  code of function that starts subroutine
  270.         xor     al,al             ;  AL =0 -start subroutine
  271.         int     21h               ;  EXEC - execution
  272.         mov     bx,ax             ;  termination code of  EXEC
  273.         mov     CS:FLAG1,0        ;  clear job activity flag
  274.         jnc     Exit0             ;  normal termination
  275. ;  Determination of error type and message output (CF =1)
  276.         mov     ax,cs             ;
  277.         mov     ds,ax             ;  segment address of path and name of file
  278.         dec     bx                ;
  279.         shl     bx,1              ;  *2
  280.         lea     bx,ADRERR [bx]    ;  address of element of addresses table
  281.         mov     bx,[bx]           ;  address mof message
  282.         Call    ERROR             ;  output error message
  283. ;  Restore old process (address of PSP  of interrupted program)
  284. Exit0:  Call    RESTSCR           ;  restore screen
  285.         cli                       ;
  286.         mov     bx,CS:OLDPSP      ;  PSP  of interrupted process
  287.         mov     ah,50h            ;
  288.         int     21h               ;  SetProcess
  289.         cli                       ;
  290.         lds     dx,CS:DTAADR      ;  address of  DTA of interrupted program
  291.         mov     ah,1Ah            ;
  292.         int     21h               ;  return  DTA  of interrupted program
  293.         mov     SS,CS:SSKEEP      ;  restore  SS register
  294.         mov     SP,CS:SPKEEP      ;  restore  SP register
  295.         POPR                      ;  registers of interrupted job
  296.         IRET                      ;  return to point of interrupt
  297. ACTIV   ENDP
  298.  
  299. ;----------------------------------------------------------
  300. ;
  301. ;  Procedure for handling  INT 13h (disk exchange) interrupt
  302. ;
  303. ;
  304. ;----------------------------------------------------------
  305. INT13H  PROC    FAR
  306.         mov     CS:InBios,1             ;  disk activity flag
  307.         pushf                           ;  flags register for  IRET (INT 13H)
  308.         Call    CS:OLD13H               ;  call old handler for INT 13H
  309.         mov     CS:InBios,0             ;  disk is not active
  310.         IRET                            ;
  311. INT13H  ENDP
  312.  
  313. ;----------------------------------------------------------
  314. ;
  315. ;  Procedure for handling  INT 28h interrupt
  316. ;
  317. ;
  318. ;----------------------------------------------------------
  319. INT28H  PROC    FAR
  320.         pushf                        ;  flags register for  IRET (INT 28h)
  321.         Call    CS:OLD28H            ;  call old handler for  INT 28H
  322.         cli                          ;  disable all interrupts
  323. ;  Check the "hot" key pressing
  324.         cmp     CS:FLAG0,1           ;  job started ?
  325.         jne     RET28                ;
  326.         cmp     CS:FLAG1,1           ;  job active ?
  327.         je      RET28                ;  wait for termination
  328.         cmp     CS:InBios,1          ;  disk exchange ?
  329.         je      RET28                ;  wait for termination
  330.         PUSHR   <es,bx>              ;
  331.         LES     bx,CS:DOSFLG         ;  address of  DOS activity flag
  332.         cmp     byte ptr ES:[bx],0   ;  DOS  not active ?
  333.         POPR    <bx,es>              ;
  334.         jnz     RET28                ;  wait for termination
  335. ;  Constructing stack for starting a job (on IRET from  INT 28h)
  336.         PUSHR                        ;  registers of interrupted job
  337.         pushf                        ;  flags register for IRET (INT 28h)
  338.         push    cs                   ;  segment address for exit
  339.         lea     cx,ACTIV             ;  address of program for starting job
  340.         push    cx                   ;  put onto stack for  IRET
  341.         IRET                         ;
  342. ;  Restoring registers and exit
  343. RET28:  sti                          ;  enable all interrupts
  344.         IRET                         ;
  345. INT28H  ENDP
  346.  
  347. ;-----------------------------------------------------------
  348. ;
  349. ;  Subroutine for error message output
  350. ;
  351. ;  BX  -address of start of a text string
  352. ;
  353. ;
  354. ;
  355. ;-----------------------------------------------------------
  356. ERROR   PROC    NEAR
  357.         PUSHR                     ;  save registers
  358.         mov     bp,80             ;  characters count
  359.         mov     dh,24             ;  line of output =25
  360.         mov     dl,0              ;  column of output =1
  361.         Call    PUTSTR            ;  output message
  362.         mov     di,1000           ;  signal frequency  1000 h
  363.         mov     bx,25             ;  time of signal  0.25 seconds
  364.         Call    SOUND             ;  output sound signal
  365.         mov     cx,20             ;  time of delay (in ticks)
  366.         Call    DELAY             ;  generate delay
  367.         POPR                      ;  restore registers
  368.         RETN                      ;
  369. ERROR   ENDP
  370.  
  371. ;-----------------------------------------------------------
  372. ;
  373. ;  Subroutine for screen output of text
  374. ;
  375. ;  BX  -address of text string start
  376. ;
  377. ;  BP  -characters counter
  378. ;
  379. ;  DH  -starting line of cursor  (0 --- 24)
  380. ;
  381. ;  DL  -starting column of cursor (0 --- 79)
  382. ;
  383. ;
  384. ;  On achieving  0  remained part of string is cleared
  385. ;
  386. ;
  387. ;
  388. ;
  389. ;-----------------------------------------------------------
  390. PUTSTR  PROC    NEAR
  391.         mov     byte ptr CS:EOS,0       ;  clear End Of String flag
  392. Cycle1: push    bx                      ;  save address of character
  393.         xor     bh,bh                   ;  screen N  0
  394.         mov     ah,2                    ;  function of cursor setting
  395.         int     10h                     ;  set cursor
  396.         pop     bx                      ;  restore address of character
  397.         mov     al,[bx]                 ;
  398.         cmp     byte ptr CS:EOS,0       ;  is end of string achieved ?
  399.         jz      Zero                    ;
  400.         mov     al,' '                  ;  transmitt space
  401.         jmp     short  Putsym           ;
  402. ;  Check for End Of String (character =0)
  403. Zero:   and     al,al                   ;  End Of String ?
  404.         jnz     Putsym                  ;
  405.         mov     CS:DL0,dl               ;  position for cursor setting
  406.         mov     byte ptr CS:EOS,1       ;  End Of Sring is found
  407. Putsym: mov     ah,07h                  ;  grey characters on dark background
  408.         Call    WRCHAR                  ;  write character to the cursor position
  409.         inc     bx                      ;  modify address of text
  410.         inc     dl                      ;  modify cursor position
  411.         dec     bp                      ;  counter of rest of characters
  412.         jg      Cycle1                  ;  to the start of cycle
  413. ;  Set cursor to the end of the output line
  414.         xor     bh,bh                   ;  screen # 0
  415.         mov     ah,2                    ;  function for cursor setting
  416.         mov     dl,CS:DL0               ;  position for cursor setting
  417.         int     10h                     ;  set cursor
  418.         RETN
  419. PUTSTR  ENDP
  420.  
  421. ;-----------------------------------------------------------
  422. ;
  423. ;  Subroutine for writing character to cursor position
  424. ;
  425. ;  AL  -character being written
  426. ;
  427. ;  AH  -required attribute
  428. ;
  429. ;
  430. ;-----------------------------------------------------------
  431. WRCHAR  PROC    NEAR
  432.         push    bx                ;
  433.         mov     bx,ax             ;  save character + attribute
  434.         mov     al,dh             ;  multiplier - line of cursor
  435.         mov     cl,160            ;  multiplier =160
  436.         mul     cl                ;  calculate offset of video buffer
  437.         xor     cx,cx             ;
  438.         mov     cl,dl             ;  to add cursor column
  439.         sal     cx,1              ;  *2
  440.         add     ax,cx             ;  offset is calculated
  441. ;  Writing one character + attribute to video buuffer
  442.         mov     di,ax             ;
  443.         mov     ax,CS:VIDEO       ;  segment address of video buffer
  444.         mov     ES,ax             ;
  445.         mov     ES:[DI],bx        ;  move character + attribute
  446.         add     DI,2              ;
  447.         pop     bx
  448.         RETN
  449. WRCHAR  ENDP
  450.  
  451. ;-----------------------------------------------------------
  452. ;
  453. ;  Subroutine for generating of delay (in ticks)
  454. ;
  455. ;  CX  -time of delay
  456. ;
  457. ;
  458. ;-----------------------------------------------------------
  459. DELAY   PROC    NEAR
  460.         PUSHR   <ax,dx,es>
  461.         mov     ax,40h               ;
  462.         mov     ES,ax                ;  segment address of BIOS area
  463.         sti                          ;  enable interrupts
  464. T0:     mov     dx,ES:[6Ch]          ;  starting time (in ticks)
  465. T1:     cmp     dx,ES:[6Ch]          ;  has time  gone ?
  466.         je      T1                   ;  no !!!
  467.         loop    T0                   ;
  468.         POPR    <es,dx,ax>
  469.         RETN
  470. DELAY   ENDP
  471.  
  472. ;----------------------------------------------------------
  473. ;
  474. ;  Subroutine for outputting sound of a given tone
  475. ;
  476. ;  Frequency   -  di register (from  21  to  65535  h)
  477. ;
  478. ;  Duration -  bx register (in hundredths of second)
  479. ;
  480. ;
  481. ;
  482. ;----------------------------------------------------------
  483. SOUND    PROC   NEAR
  484.          PUSHR
  485.          mov    al,0B6h           ;  write timer mode
  486.          out    43h,al            ;  write to control register
  487.          mov    dx,14h            ;  high part of divisor
  488.          mov    ax,4F38h          ;  DX:AX = 1331000
  489.          div    di                ;  1331000/frequency
  490.          out    42h,al            ;  write low part
  491.          mov    al,ah             ;
  492.          out    42h,al            ;  write high part
  493.          in     al,61h            ;  read port B
  494.          mov    ah,al             ;  remember state of port B
  495.          or     al,3              ;  resolution of timer and sound
  496.          out    61h,al            ;
  497. ;  Generation of delay in hundredth of second (value in   BX)
  498. Waitr:   mov    cx,2801           ;  duration 0.01 s
  499.          loop   $                 ;  delay  0.01 s
  500.          dec    bx                ;  has time gone ?
  501.          jnz    Waitr             ;  no
  502.          mov    al,ah             ;
  503.          out    61h,al            ;  restore state of port B
  504.          POPR                     ;
  505.          RETN                     ;
  506. SOUND    ENDP
  507.  
  508. ;----------------------------------------------------------
  509. ;
  510. ;  Procedure for saving the state of screen
  511. ;
  512. ;
  513. ;----------------------------------------------------------
  514. SAVESCR PROC    NEAR
  515.         cmp     byte ptr CS:SAV,0 ;  to save creen or not ?
  516.         jz      ExitS             ;
  517.         PUSHR                     ;
  518.         mov     ah,0Fh            ;  function for reading current mode
  519.         int     10h               ;  determine current mode
  520.         mov     CS:MODE,al        ;  sceen mode is read
  521.         mov     ah,3              ;  read cursor position
  522.         xor     bh,bh             ;  page number
  523.         int     10h               ;
  524.         mov     CS:CURSY,dh       ;  cursor line
  525.         mov     CS:CURSX,dl       ;  cursor column
  526. ;  Read video buffer for saving
  527.         mov     ax,CS:VIDEO       ;  address of video buffer
  528.         mov     ds,ax             ;  move it to DS
  529.         push    cs                ;
  530.         pop     es                ;  output data segment
  531.         xor     si,si             ;  address of start of video buffer
  532.         lea     di,BUFER          ;  address of saving buffer
  533.         cld                       ;  direction - forward !
  534.         mov     cx,2000           ;  number of words
  535.         rep     movsw             ;  read  2000  words of screen
  536.         POPR                      ;
  537. ExitS:  RETN
  538. SAVESCR ENDP
  539.  
  540. ;----------------------------------------------------------
  541. ;
  542. ;  Procedure for restoring screen state
  543. ;
  544. ;
  545. ;----------------------------------------------------------
  546. RESTSCR PROC    NEAR
  547.         cmp     byte ptr CS:SAV,0 ;  to restore screen or not ?
  548.         jz      ExitR             ;
  549.         PUSHR                     ;
  550.         xor     ah,ah             ;  function for setting mode
  551.         mov     al,CS:MODE        ;  read screen mode
  552.         int     10h               ;  set screen mode
  553. ;  Restoring video buffer
  554.         mov     ax,CS:VIDEO       ;  address of video buffer
  555.         mov     es,ax             ;  address to ES
  556.         push    cs                ;
  557.         pop     ds                ;  original data segment
  558.         lea     si,BUFER          ;  address of saving buffer
  559.         xor     di,di             ;  address of start of video buffer
  560.         cld                       ;  direction - forward !
  561.         mov     cx,2000           ;  number of words
  562.         rep     movsw             ;  restore  2000  words of screen
  563. ;  Restoring position of cursor
  564.         mov     ah,2              ;  set cursor position
  565.         xor     bh,bh             ;  number of page
  566.         mov     dh,CS:CURSY       ;  cursor line
  567.         mov     dl,CS:CURSX       ;  cursor column
  568.         int     10h               ;
  569.         POPR                      ;
  570. ExitR:  RETN
  571. RESTSCR ENDP
  572.  
  573. ;----------------------------------------------------------
  574. ;
  575. ;
  576. ;  Procedure for deinstallation of  TSRPGM driver
  577. ;
  578. ;
  579. ;
  580. ;----------------------------------------------------------
  581. DEINST  PROC    NEAR
  582.         LES     bx,CS:DOSFLG            ;  address of DOS activity flag
  583.         cmp     byte ptr ES:[bx],0      ;  is not DOS active ?
  584.         jnz     RDINST                  ;  wait for termination
  585. ;
  586.         Call    SAVESCR           ;  save screen
  587.         cli                       ;  disable interrupts for time of substitution
  588.         mov     ax,cs             ;  data segment in code segment
  589.         mov     ds,ax             ;
  590.         lds     dx,OLD08H         ;  DS:DX -address of old vector
  591.         mov     ax,2508H          ;  return old interrupt vector for INT 08H
  592.         int     21h               ;
  593. ;
  594.         mov     ax,cs             ;  data segment in code segment
  595.         mov     ds,ax             ;
  596.         lds     dx,OLD09H         ;  DS:DX -address of old vector
  597.         mov     ax,2509H          ;  return old interrupt vector for  INT 09H
  598.         int     21h               ;
  599. ;
  600.         mov     ax,cs             ;  data segment in code segment
  601.         mov     ds,ax             ;
  602.         lds     dx,OLD13H         ;  DS:DX -address of old vector
  603.         mov     ax,2513H          ;  return old interrupt vector for   INT 13H
  604.         int     21h               ;
  605. ;
  606.         mov     ax,cs             ;  data segment in code segment
  607.         mov     ds,ax             ;
  608.         lds     dx,OLD28H         ;  DS:DX -address of old vector
  609.         mov     ax,2528H          ;  return old interrupt vector for   INT 28H
  610.         int     21h               ;
  611. ;  Output message about deinstallation of driver
  612.         mov     ax,cs             ;  data segment in code segment
  613.         mov     ds,ax             ;
  614.         lea     bx,TEXT0          ;  address of text
  615.         mov     bp,80             ;  characters counter
  616.         mov     dh,24             ;  line of output =25
  617.         mov     dl,0              ;  column of output =1
  618.         Call    PUTSTR            ;  output string of message
  619.         mov     cx,15             ;  time of delay (in ticks)
  620.         Call    DELAY             ;  generate delay
  621.         Call    RESTSCR           ;  restore screen
  622. ;  Releasing memory occupied by driver
  623.         mov     ax,cs             ;  data segment in code segment
  624.         mov     ds,ax             ;
  625.         mov     es,ax             ;
  626.         mov     ah,49h            ;  FREEMAIN
  627.         int     21h               ;  release memory
  628.         sti                       ;  enable inerrupts
  629. RDINST: RETN
  630. DEINST  ENDP
  631. ;
  632. BUFER   DB      4000 dup (0)      ;  buffer for  saving screen
  633. ;
  634. ;----------------------------------------------------------
  635. ;
  636. ;  Program for initial loading of  resident part of driver
  637. ;
  638. ;
  639. ;----------------------------------------------------------
  640. ;  Check for presence already loaded driver  TSRPGM
  641. BEGIN:  mov     ax,3509h          ;  read address of current vector for INT 09h
  642.         int     21h               ;  ES:BX  -address of vector
  643.         mov     ax,es:[bx-2]      ;  driver presence code
  644.         mov     LOD,0             ;  don't load driver
  645.         cmp     ax,PRES0          ;  is driver in memory already ?
  646.         je      M20               ;  yes, process parameters
  647.         mov     LOD,1             ;  loading of driver is required
  648.         mov     ax,cs             ;
  649.         mov     ES,ax             ;
  650.         lea     di,INT09H         ;  ES:DI -address of new vector  INT09H
  651.         jmp     short M21
  652. ;  Processing command string (if present)
  653. M20:    xor     di,di                   ;
  654.         mov     ES,di                   ;  segment address =0
  655.         les     di,ES:[24h]             ;  ES:DI  -address of old vector
  656. M21:    mov     ADRINT,di               ;  address of start of vector for INT09H
  657.         mov     bx,80h                  ;  address of length of parameters field
  658.         mov     cl,[bx]                 ;  length of parameters field
  659.         xor     ch,ch                   ;  CX -length of command string
  660.         and     cl,cl                   ;  are parameters absent ?
  661.         jz      NOPARM                  ;  they're absent !!!
  662.         inc     bx                      ;
  663. ;  Processing parameters of command string
  664. M22:    mov     al,[bx]                 ;  character from command string
  665.         cmp     al,'/'                  ;  start of parameter ?
  666.         je      M23                     ;
  667.         inc     bx                      ;  address of next character
  668.         loop    M22                     ;  to start of cycle
  669.         jmp     ERPARM                  ;
  670. ;----------------------------------------------------------
  671. ;  Outputting message about absence of parameters and request for input
  672. NOPARM: lea     dx,ERR1                 ;  parameters are absent
  673.         mov     ax,cs                   ;  data segment in code segment
  674.         mov     ds,ax                   ;
  675.         mov     ah,9                    ;  code of text output function
  676.         int     21h                     ;  output message
  677. TASK2:  lea     dx,ERR2                 ;  parameters are absent
  678.         mov     ax,cs                   ;  data segment in code segment
  679.         mov     ds,ax                   ;
  680.         mov     ah,9                    ;  code of text output function
  681.         int     21h                     ;  output message
  682.         lea     dx,ERR3                 ;  parameters are absent
  683.         mov     ah,9                    ;  code of text output function
  684.         int     21h                     ;  output message
  685.         Call    INPUT                   ;  request for  parameters input
  686.         mov     cl,LENG                 ;  length of field
  687.         cmp     LENG,0                  ;  esmty input ?
  688.         jna     Exit00                  ;  exit
  689.         lea     bx,PARM                 ;  parametrs field from  PARM string
  690.         cmp     byte ptr PARM,'/'       ;
  691.         je      M23                     ;  continue work
  692.         lea     bx,PARM-1               ;  parametrs field from  PARM string
  693.         jmp     short M23               ;  path without "/"
  694. Exit00: mov     ax,4c00h                ;  terminate program with 0 code
  695.         int     21h                     ;  return to  MS-DOS
  696. ;  Output message on error in parameters
  697. ERPARM: lea     dx,ERR4                 ;  error in parameters
  698.         mov     ax,cs                   ;  data segment in code segment
  699.         mov     ds,ax                   ;
  700.         mov     ah,9                    ;  code of text output function
  701.         int     21h                     ;  output message
  702.         jmp     short TASK2             ;
  703. ;----------------------------------------------------------
  704. ;  Clearing the path of file being loaded
  705. ;  ES:DI  -address of entry point of   INT09H (in the program)
  706. M23:    push    cx                      ;  counter for length of  PARM  field
  707.         inc     bx                      ;
  708.         mov     cx,64                   ;  length of path
  709.         xor     al,al                   ;
  710.         sub     di,66                   ;  address of start of PATH
  711.         cld                             ;
  712.         rep     stosb                   ;  clear  PATH (ES:DI)
  713.         pop     cx                      ;
  714. ;  Passing from the PARM field the path for file being loaded (DS:BX)
  715.         sub     di,64                   ;  address of start of   PATH
  716. M24:    mov     al,[bx]                 ;  character of name from PARM (DS:BX)
  717.         cmp     al,' '                  ;  end of name ?
  718.         jna     M25                     ;
  719.         stosb                           ;  pass character to  PATH
  720.         inc     bx                      ;  address of next character from PARM
  721.         loop    M24                     ;  to the start of the cycle
  722. ;  Search for parameter of video buffer saving:  /S (while loading only)
  723. M25:    mov     BX0,bx                  ;  address of next character
  724.         mov     CX0,cx                  ;  length of the rest of parameters field
  725.         jcxz    M27                     ;  no additional parameters
  726.         cmp     LOD,1                   ;  is loading required ?
  727.         jne     M26                     ;  no, parameter can't be defined
  728.         lea     si,PSAV                 ;  address of standard
  729.         mov     dx,Lpsav                ;  length of standard
  730.         Call    COMPAR                  ;  search for key parameter
  731.         mov     di,ADRINT               ;  address of start of vector  INT09H
  732.         mov     byte ptr ES:[di]-81,0   ;  clear screen saving flag
  733.         jc      M26                     ;  parameter not found
  734.         mov     byte ptr ES:[di]-81,1   ;  screen saving flag
  735. ;  Search for the prescribed "hot" key code: /K=KEY0   (Alt + KEY0)
  736. M26:    mov     bx,BX0                  ;  address of next character after   PATH
  737.         mov     cx,CX0                  ;  length of the rest of parameters field
  738.         lea     si,PKEY                 ;  address of standard
  739.         mov     dx,Lpkey                ;  length of standard
  740.         Call    COMPAR                  ;  search for key parameter
  741.         mov     di,ADRINT               ;  address of start of vector  INT09H
  742.         mov     byte ptr ES:[di]-82,40h ;  F6 key code
  743.         jc      M27                     ;  parameter not found
  744.         mov     ax,[bx]                 ;  address of given key code
  745.         Call    SYMHEX                  ;
  746.         jc      M27                     ;  transformation error
  747.         mov     ES:[di]-82,al           ;  prescribed "hot" key code
  748. M27:
  749. ;  Output message onchanging parameters of driver
  750.         cmp     LOD,1                   ;  is load required ?
  751.         je      REGIM                   ;  yes, it is
  752.         mov     di,1000                 ;  frequency  1000 h
  753.         mov     bx,25                   ;  duration  0.25 s
  754.         Call    SOUND                   ;  output sound signal
  755.         lea     dx,LOAD1                ;
  756.         mov     ah,9                    ;  code of text output function
  757.         int     21h                     ;  output message
  758.         mov     ax,4c00h                ;  terminate program with 0 code0
  759.         int     21h                     ;  return to  MS-DOS
  760. ;----------------------------------------------------------
  761. ;  Determining the segment address of video buffer
  762. REGIM:   mov    ax,cs               ;
  763.          mov    ds,ax               ;  data segment in code segment
  764.          mov    VIDEO,0B000H        ;  address of video buffer for monochrom display
  765.          mov    ax,40h              ;  segment address of  BIOS area
  766.          mov    ES,ax               ;  ES -address of  BIOS data area
  767.          mov    al,ES:[10h]         ;  read hardware list  0040 : 0010
  768.          and    al,30h              ;  clear bits out of interest
  769.          cmp    al,30h              ;  is it a monochrom display ?
  770.          je     Modvec              ;  yes !
  771.          mov    VIDEO,0B800H        ;  address of video buffer for color display
  772. ;  Get the address of DOS activity flag (int 34h)
  773. MODVEC: mov     ah,34h            ;  Get the address of DOS activity flag
  774.         int     21h               ;  address of flag in  ES:BX
  775.         mov     SEGFLG,ES         ;
  776.         mov     OFFFLG,BX         ;
  777.         mov     PSP0,cs           ;
  778.         cli                       ;  disable interrupts for the time of substitution
  779. ;  Reading and saving the old vector  INT08H
  780.         mov     ax,3508h          ;  read  address of current vector INT 08h
  781.         int     21h               ;  ES:BX  -address been read
  782.         mov     OFF08H,bx         ;  pass address of old vector
  783.         mov     SEG08H,es         ;  pass segment address of old vector
  784.         lea     dx,INT08H         ;  DS:DX -address of new vector
  785.         mov     ax,2508h          ;  activate new interrupt  INT 08h  vector
  786.         int     21h               ;
  787. ;  Modify address of keyboard interrupt INT 09H vector
  788.         mov     ax,3509h          ;  read  address of current vector  INT 09h
  789.         int     21h               ;  ES:BX  -address been read
  790.         mov     OFF09H,bx         ;  pass address of old vector
  791.         mov     SEG09H,es         ;  pass segment address of old vector
  792.         lea     dx,INT09H         ;  DS:DX -address of new vector
  793.         mov     ax,2509h          ;  activate new interrupt  vector  INT 09h
  794.         int     21h               ;
  795. ;  Reading and modyfying an old vector for interrupt 13h
  796.         mov     ax,3513H          ;  read  address of current vector  INT 13H
  797.         int     21h               ;  ES:BX  -address been read
  798.         mov     OFF13H,bx         ;  pass address of old vector
  799.         mov     SEG13H,es         ;  pass segment address of old vector
  800.         lea     dx,INT13H         ;  DS:DX -address of new vector
  801.         mov     ax,2513H          ;  activate new interrupt  vector   INT 13H
  802.         int     21h               ;
  803. ;  Reading and modyfying an old vector for interrupt 28h
  804.         mov     ax,3528h          ;  read  address of current vector  INT 28h
  805.         int     21h               ;  ES:BX  -address been read
  806.         mov     OFF28H,bx         ;  pass address of old vector
  807.         mov     SEG28H,es         ;  pass segment address of old vector
  808.         lea     dx,INT28H         ;  DS:DX -address of new vector
  809.         mov     ax,2528h          ;  activate new interrupt  vector  INT 28h
  810.         int     21h               ;
  811.         sti                       ;  enable interrupts (substitutions have been performed)
  812. ;  Loading the resident part of the program
  813.         lea     dx,LOAD0          ;  address of message
  814.         mov     ah,9              ;  code of text output function
  815.         int     21h               ;  output message on driver loading
  816.         lea     dx,BEGIN          ;  length of resident part  (byte)
  817.         cmp     SAV,1             ;  to save screen ?
  818.         je      KEEP              ;
  819.         lea     dx,BUFER          ;  length of resident part without  BUFER
  820. KEEP:   mov     cl,4              ;
  821.         shr     dx,cl             ;  length of resident part in paragraphs
  822.         add     dx,20             ;  16  paragraphs for  PSP + 4
  823.         mov     ax,3100h          ;  terminate and state resident
  824.         int     21h               ;  KEEP
  825.  
  826. ;----------------------------------------------------------
  827. ;
  828. ;
  829. ;  Procedure for parameters input (path of job to be started)
  830. ;
  831. ;  ES:DI  -address of INT09H  vector
  832. ;
  833. ;  CX     -lenth of string input (on exitting procedure)
  834. ;
  835. ;
  836. ;
  837. ;----------------------------------------------------------
  838. INPUT   PROC    NEAR
  839.         PUSHR
  840.         PUSHR   <es,di>                 ;  ES:DI  -address  INT09H
  841.         push    cs                      ;
  842.         pop     es                      ;  data segment in code segment
  843.         lea     di,LENG                 ;  address for start of clearing
  844.         mov     cx,81                   ;  length of string being cleared
  845.         xor     al,al                   ;  clearing character =0
  846.         cld                             ;
  847.         rep     stosb                   ;  clear string
  848.         lea     dx,MAX                  ;  DS:DX -address of start of string
  849.         mov     ah,0Ah                  ;  input string
  850.         int     21h                     ;
  851. ;  Passing the input parameters to the  PARM field
  852.         POPR    <di,es>                 ;  ES:DI  -address of INT09H
  853.         sub     di,66                   ;  address of start of PATH
  854.         xor     ch,ch                   ;  clear high part
  855.         mov     cl,LENG                 ;  length of input information
  856.         lea     si,PARM                 ;
  857.         rep     movsb                   ;  pass the path been input
  858.         mov     byte ptr es:[di],0      ;  end of path indicator
  859.         POPR                            ;
  860.         RETN                            ;  exit
  861. INPUT   ENDP
  862.  
  863. ;----------------------------------------------------------
  864. ;
  865. ;
  866. ;  Procedure for search of a given key word in  PARM field
  867. ;
  868. ;  DS:BX  -address of start of parameters field on running
  869. ;
  870. ;  DS:SI  -address of standard (key word)
  871. ;
  872. ;  DX     -length of standard
  873. ;
  874. ;  CX     -length of field for parameter search
  875. ;
  876. ;  CF =1  -parameter is not found
  877. ;
  878. ;
  879. ;
  880. ;----------------------------------------------------------
  881. COMPAR  PROC    NEAR
  882. ;  Reducing letters to capitals
  883. M100:   mov     al,[bx]                 ;  character from  PARM field
  884.         cmp     al,'a'                  ;  character < a ?
  885.         jb      M101                    ;
  886.         cmp     al,'z'                  ;  character > z ?
  887.         ja      M101                    ;
  888.         and     al,0DFh                 ;  reduce to capitals
  889. ;  Searching for coinsiding characters of parameter string and standard
  890. M101:   cmp     [si],al                 ;  is character of standard found ?
  891.         je      M102                    ;  compare next character
  892.         inc     bx                      ;  address of nextcharacter from  PARM
  893.         loop    M100                    ;  continue search
  894.         jmp     short  Nocomp           ;  paramener not found
  895. M102:   inc     si                      ;  address of next byte of standard
  896.         inc     bx                      ;  address of next byte of   PARM
  897.         dec     dx                      ;  length of rest of standard
  898.         jz      Normal                  ;
  899.         loop    M100                    ;  continue search
  900. ;  Exit on key parameter not found
  901. Nocomp: stc                             ;  CF =1 - error indicator
  902.         RETN                            ;  exit
  903. ;  Exit on key parameter  found
  904. Normal: clc                             ;  clear carry flag
  905.         RETN                            ;  exit
  906. COMPAR  ENDP
  907.  
  908. ;------------------------------------------------------------------------
  909. ;
  910. ;  Transforming two characters into byte   (ASCII ---> HEX)
  911. ;
  912. ;  Input:
  913. ;  -----
  914. ;  AH  -lower byte of a numeral (transformed into right nybble)
  915. ;  AL  -higher byte of a numeral (transformed into left nybble)
  916. ;
  917. ;  Output:
  918. ;  ------
  919. ;  AL  -output result (two nybbles for hex numerals)
  920. ;
  921. ;  CF =1 -transformation error code
  922. ;
  923. ;
  924. ;
  925. ;
  926. ;------------------------------------------------------------------------
  927. ;
  928. SYMHEX  PROC    NEAR
  929.         Call    TRANS             ;  transforming numeral from AL
  930.         jc      ExitH             ;  exit on error
  931.         shl     al,1              ;  shift nybble to the left  (higher part)
  932.         shl     al,1              ;
  933.         shl     al,1              ;
  934.         shl     al,1              ;  left nybble  of result is in AL
  935.         xchg    al,ah             ;  AL - higher byte for right nybble
  936.         Call    TRANS             ;  transform character from  AL
  937.         jc      ExitH             ;  exit on error
  938.         or      al,ah             ;  merge right + left nybbles
  939.         clc                       ;  normal transformation indicator
  940. ExitH:  RETN                      ;  result in AL
  941. SYMHEX  ENDP
  942.  
  943. ;----------------------------------------------------------
  944. ;
  945. ;  Transforming a character into a hex
  946. ;
  947. ;  AL  -given character of hex numeral (ASCII -input)
  948. ;
  949. ;  AL  -transformed hex numeral (right nybble)
  950. ;
  951. ;
  952. ;
  953. ;----------------------------------------------------------
  954. TRANS   PROC    NEAR
  955.         cmp     al,30h            ;  character < 0 ?
  956.         jl      ErrorH            ;  error
  957.         cmp     al,39h            ;  character >  9 ?
  958.         jg      Caps              ;  test for capitals A----F
  959.         sub     al,30h            ;  subtract constant for ciphers
  960.         jmp     short Eoc         ;
  961. ;  Transforming capitals    A----F
  962. Caps:   cmp     al,41h            ;  character < A ?
  963.         jl      ErrorH            ;  error
  964.         cmp     al,46h            ;  character > F ?
  965.         jg      Little            ;  test for small letters a --- f
  966.         sub     al,37h            ;  subtract constant for small letters
  967.         jmp     short Eoc         ;
  968. ;  Transforming small letters  a----f
  969. Little: cmp     al,61h            ;  character < a ?
  970.         jl      ErrorH            ;  error
  971.         cmp     al,66h            ;  character > F ?
  972.         jg      ErrorH            ;  error
  973.         sub     al,57h            ;  subtract constant for small letters
  974. ; Transformation  peformed without errors
  975. Eoc:    clc                       ;  clear carry flag
  976.         RETN                      ;  normal exit
  977. ;  Error on character transformation error
  978. ErrorH: stc                       ;  carry flag on error
  979.         RETN
  980. TRANS   ENDP
  981.  
  982. ;----------------------------------------------------------
  983. LOD     DB      0                 ;
  984. PRES0   DW      1234              ;  driver presence code
  985. ADRINT  DW      0                 ;  address of entry point of  INT09H vector
  986. BX0     DW      0                 ;  address after path in PARM field
  987. CX0     DW      0                 ;  length of rest of parameters field
  988. PSAV    DB      '/S'              ;
  989. Lpsav   EQU     $-PSAV
  990. PKEY    DB      '/K='             ;
  991. Lpkey   EQU     $-PKEY
  992. LOAD0   DB      10,13,'Driver  *** TSRPGM ***  is loaded $ ',13,10
  993. LOAD1   DB      10,13,'*** TSRPGM ***  Parameters are changed !!! $ ',13,10
  994. ERR1    DB      10,13,'*** TSRPGM ***  Parameters are absent !!!$'
  995. ERR2    DB      10,13,'                Alt + Shift (Right) -deinstallation$'
  996. ERR3    DB      10,13,'Define:        /PATH [/S] [/K=KEY] ', 13, 10, '$'
  997. ERR4    DB      10,13,'*** TSRPGM ***  Errors in parameters !!!$ '
  998.         DB      13,10
  999. MAX     DB      80                ;  maximum length of input string
  1000. LENG    DB      0                 ;  actual length of input string
  1001. PARM    DB      80 dup (0)        ;  information been input (without  CR)
  1002. CODE    ENDS
  1003.         END     START
  1004.